﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Mvc.Html;

namespace WikeSoft.Core.Extension
{
    /// <summary>
    /// htmlhelper扩展
    /// </summary>
    public static class HtmlHelperExtensions
    {
        /// <summary>
        /// 通过枚举生成下来列表
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="enumType"></param>
        /// <returns></returns>
        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumType)
        {
            return htmlHelper.DropDownListFor(expression, enumType, null);
        }

        /// <summary>
        /// 通过枚举生成下来列表
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="enumType"></param>
        /// <param name="allText">默认值</param>
        /// <returns></returns>
        public static MvcHtmlString DropDownListForAll<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumType, string allText)
        {
            return htmlHelper.DropDownListForAll(expression, enumType, allText, null);
        }
        /// <summary>
        /// 通过枚举生成下来列表
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="enumType">枚举类型</param>
        /// <param name="allText"></param>
        /// <param name="htmlAttributes">html属性</param>
        /// <param name="exceptValues">排除值</param>
        /// <returns></returns>
        public static MvcHtmlString DropDownListForAll<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumType,string allText, object htmlAttributes, params object[] exceptValues)
        {
            var options = EnumUtility.GetValuesWithNullableValue(enumType,allText, exceptValues);
            return htmlHelper.DropDownListFor(expression, options, htmlAttributes);
        }

        /// <summary>
        /// 通过枚举生成下来列表
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="id">控件Id</param>
        /// <param name="enumType">枚举类型</param>
        /// <param name="allText"></param>
        /// <param name="htmlAttributes">html属性</param>
        /// <param name="exceptValues">排除值</param>
        /// <returns></returns>
        public static MvcHtmlString DropDownListAll(this HtmlHelper htmlHelper, string id, Type enumType, string allText,
        object htmlAttributes, params object[] exceptValues)
        {
            var options = EnumUtility.GetValuesWithNullableValue(enumType, allText, exceptValues);
            
            MvcHtmlString mvcHtmlString = htmlHelper.DropDownList(id, options, htmlAttributes);
            
            return mvcHtmlString;
        }

        /// <summary>
        /// 通过枚举生成下来列表
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="id">控件Id</param>
        /// <param name="enumType">枚举类型</param>
        
        /// <param name="htmlAttributes">html属性</param>
        /// <param name="exceptValues">排除值</param>
        /// <returns></returns>
        public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string id, Type enumType, 
        object htmlAttributes, params object[] exceptValues)
        {
            var options = EnumUtility.GetValues(enumType, exceptValues);

            return htmlHelper.DropDownList(id, options, htmlAttributes);
        }

        /// <summary>
        /// 自定义下拉列表框
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="enumType"></param>
        /// <param name="htmlAttributes"></param>
        /// <param name="exceptValues">排除的值</param>
        /// <returns></returns>
        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumType, object htmlAttributes, params object[] exceptValues)
        {
            var options = EnumUtility.GetValues(enumType, exceptValues);

            return htmlHelper.DropDownListFor(expression, options, htmlAttributes);
        }

        /// <summary>
        /// 自定义下拉列表框
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="expression"></param>
        /// <param name="enumType"></param>
        /// <param name="selectedVal">选中的值</param>
        /// <param name="htmlAttributes"></param>
        /// <param name="exceptValues">排除的值</param>
        /// <returns></returns>
        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Type enumType, object selectedVal, object htmlAttributes, params object[] exceptValues)
        {
            var options = EnumUtility.GetValues(enumType, exceptValues).ToList();
            var selItem = options.FirstOrDefault(c => c.Value == selectedVal.ToString());
            if (selItem != null)
            {
                selItem.Selected = true;
            }
            return htmlHelper.DropDownListFor(expression, options, htmlAttributes);
        }

        /// <summary>
        /// 自定义下拉列表框
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <typeparam name="TProperty"></typeparam>
        /// <param name="htmlHelper"></param>
        /// <param name="enumType"></param>
        /// <param name="selectedVal">选中的值</param>
        /// <param name="htmlAttributes"></param>
        /// <param name="exceptValues">排除的值</param>
        /// <returns></returns>
        public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,  Type enumType, object selectedVal, object htmlAttributes, params object[] exceptValues)
        {
            var options = EnumUtility.GetValues(enumType, exceptValues).ToList();
            var selItem = options.FirstOrDefault(c => c.Value == selectedVal.ToString());
            if (selItem != null)
            {
                selItem.Selected = true;
            }
            return htmlHelper.DropDownListFor(c=>c, options, htmlAttributes);
        }

        /// <summary>
        /// 自定义下来框
        /// </summary>
        /// <param name="enumType">枚举类型</param>
        /// <param name="selectedVal">选择的值</param>
        /// <param name="name"></param>
        /// <param name="extendText">默认值</param>
        /// <param name="htmlClass">样式名称</param>
        /// <returns></returns>
        public static MvcHtmlString DropDownListFor(Type enumType, object selectedVal, string name, string extendText,string htmlClass="")
        {
            var values = Enum.GetValues(enumType).OfType<object>();
            var result = string.Format("<option>{0}</option>", extendText);

            result += values.Select(c => string.Format("<option {1}>{0}</option>", c.ToString(), GetSelected((int)c, selectedVal))).Join("");

            var html = string.Format("<select name='{0}' class='{2}'>{1}</select>", name, result,htmlClass);
            return new MvcHtmlString(html);
        }

        /// <summary>
        /// 选中
        /// </summary>
        /// <param name="val"></param>
        /// <param name="selectedVal"></param>
        /// <returns></returns>
        private static string GetSelected(object val, object selectedVal)
        {
            if (selectedVal == null)
                return string.Empty;

            if ((int)val == (int)selectedVal)
                return "selected='selected'";

            return string.Empty;
        }
    }
}
